package com.smx.xname;
import org.apache.xmlrpc.webserver.ServletWebServer;

import java.io.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.*;
import java.util.regex.*;
import java.net.InetAddress;
import java.net.MalformedURLException;

public class IPFinder {

    /**
     * @param args
     */
    private HashMap<String,Integer> ipdata;
    private static final int MIN_IP=3;
    private boolean isEnoughSourcesFound;
    private String finalIP="";
    public IPFinder(){
        resetToReadyState();
    }

    /**
     * Prepare the system for new ip configuration check
     */
    private void resetToReadyState(){
        ipdata=new HashMap<String,Integer>();
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        IPFinder app=new IPFinder();
        try {
            app.detectIP();
            System.out.println("Detected WAN IP = "+app.detectIP());

        } catch (NotEnoughSourcesException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }


    private String readURLData(String ipAddress){
        String outData=null;
        String out="";
        try{
            URL source=new URL(ipAddress);
            BufferedReader bf=new BufferedReader(
                    new InputStreamReader(source.openStream()));

            while((outData=bf.readLine())!=null){
                out+=outData+"\n";
            }
            bf.close();
        }catch(MalformedURLException ex){

        }  catch(IOException ex){

        }


        return out;
    }


    public String detectIP() throws NotEnoughSourcesException{
        resetToReadyState();
        BufferedReader  bin=null;
        try{
            bin=new BufferedReader(new InputStreamReader(new FileInputStream(com.smx.xname.util.Directory.getApplicationPath() +"//url.txt")));
            String inputline="";
            while((inputline=bin.readLine())!=null){
                findIP(readURLData(inputline));
                if(isReady()){
                    isEnoughSourcesFound=true;
                    break;
                }
            }
            if(!isEnoughSourcesFound){
                throw new NotEnoughSourcesException();
            }

        }catch(IOException ex){
            ex.printStackTrace();
        }finally{
            try{
                bin.close(); 
            }   catch(IOException ex){
                //Suppressed
            }
        }

        return finalIP;
    }

    private boolean isReady(){
        ipdata=sortHashMapByValues(ipdata, false);

        int foundips=0;
        Iterator it = ipdata.keySet().iterator();
        while (it.hasNext()) {
            String element =  (String)it.next();
            foundips=ipdata.get(element).intValue();
            if(MIN_IP>=foundips){                
                finalIP=element;
                return true;
            }
            //System.out.println("Elem="+ element + " " + ipdata.get(element).intValue());
        }

        return false;
    }

    //	http://www.theserverside.com/discussions/thread.tss?thread_id=29569
    public LinkedHashMap sortHashMapByValues(HashMap passedMap, boolean ascending) {

        List mapKeys = new ArrayList(passedMap.keySet());
        List mapValues = new ArrayList(passedMap.values());
        Collections.sort(mapValues);
        Collections.sort(mapKeys);

        if (!ascending)
            Collections.reverse(mapValues);

        LinkedHashMap someMap = new LinkedHashMap();
        Iterator valueIt = mapValues.iterator();
        while (valueIt.hasNext()) {
            Object val = valueIt.next();
            Iterator keyIt = mapKeys.iterator();
            while (keyIt.hasNext()) {
                Object key = keyIt.next();
                if (passedMap.get(key).toString().equals(val.toString())) {
                    passedMap.remove(key);
                    mapKeys.remove(key);
                    someMap.put(key, val);
                    break;
                }
            }
        }
        return someMap;
    }


    private void findIP(String _data){
        /*Original source
           * http://www.robvanderwoude.com/index.html
           * \b(([0-2]?\d{1,2}\.){3}[0-2]?\d{1,2})\b
           *
           */
        Pattern myPattern= Pattern.compile("\\b(([0-2]?\\d{1,2}\\.){3}[0-2]?\\d{1,2})\\b");
        Matcher match=myPattern.matcher( _data );
        while(match.find()){
            String matchData=match.group();
            if(ipdata.containsKey(matchData)){
                int tempInt=0;
                tempInt=((Integer)ipdata.get(matchData)).intValue()+1;
                ipdata.remove(matchData);
                ipdata.put(matchData,new Integer(tempInt));
            }else{
                ipdata.put(matchData,new Integer(1));
            }
        }
    }
}
